package lt.egidijus.aatest.popup.actions;

import java.io.File;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import lt.egidijus.aatest.filters.ATGOption;
import lt.egidijus.aatest.generator.rules.DefaultInvocationRule;
import lt.egidijus.aatest.generator.rules.GettersTestingRule;
import lt.egidijus.aatest.generator.rules.NullTestingRule;
import lt.egidijus.aatest.generator.rules.RandomTestingRule;
import lt.egidijus.aatest.generator.rules.SettersTestingRule;
import lt.egidijus.aatest.utils.Constants;
import lt.egidijus.aatest.utils.Utils;
import lt.egidijus.aatest.wizards.helpers.DefaultOptions;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.browser.TitleEvent;
import org.eclipse.swt.browser.TitleListener;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.swt.*;
import org.eclipse.swt.browser.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

@SuppressWarnings("restriction")
public class GenerateTestGeneticAction implements IObjectActionDelegate {
	
	static Browser browser;
	static String[] urls;
	static String[] titles;
	static int index;

	/**
	 * Constructor for Action1.
	 */
	public GenerateTestGeneticAction() {
		super();
	}

	private Shell shell;

	/**
	 * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
	 */
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		shell = targetPart.getSite().getShell();
	}

	List<ICompilationUnit> list = new ArrayList<ICompilationUnit>(0);

	/**
	 * @see IActionDelegate#run(IAction)
	 */
	public void run(IAction action) {
		if (Constants.clickTestProject){
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					MessageDialog.openError(null, "Generate tests", "Generate test can only in source project!");
				}
			});
			return;
		}
		List<ATGOption> rules = new ArrayList<ATGOption>();
		rules.add(new DefaultInvocationRule());
		if (Constants.generateSetMethod)
			rules.add(new SettersTestingRule());
		if (Constants.generateGetMethod)
			rules.add(new GettersTestingRule());
		rules.add(new RandomTestingRule());
		if (Constants.useNullRule)
			rules.add(new NullTestingRule());
		DefaultOptions.setDefaultRules(rules);
		
		GeneticGeneratorAction m = new GeneticGeneratorAction(list, shell);

			if (m.isAnyError()) {
				MessageDialog.openWarning(shell,
						"Not all tests were generated", m.getFailedClasses());
			} else {
				String message = "Tests were generated successfully!";
				if ((Constants.showTimes))
					message = message + m.getPerformanceTimes();
				MessageDialog.openInformation(shell, "Tests were generated", message);

			}
		list.clear();

	}

	/**
	 * @see IActionDelegate#selectionChanged(IAction, ISelection)
	 */
	public void selectionChanged(IAction action, ISelection selection) {
		list.clear();
		Utils.updateProjectsNames(selection);
		if (selection instanceof TreeSelection) {
			org.eclipse.jface.viewers.TreeSelection t = (TreeSelection) selection;
			Iterator<?> it = t.iterator();
			while (it.hasNext()) {
				Object o = it.next();
				if (o instanceof ICompilationUnit) {
					ICompilationUnit c = (ICompilationUnit) o;
					list.add(c);
				} else {
					if (o instanceof IPackageFragmentRoot) {
						IPackageFragmentRoot pack = (IPackageFragmentRoot) o;
						try {
							for (IJavaElement e : pack.getChildren()) {
								if (e instanceof PackageFragment) {
									PackageFragment p = (PackageFragment) e;
									list.addAll(Arrays.asList(p
											.getCompilationUnits()));
								}

							}
						} catch (JavaModelException e) {
							e.printStackTrace();
						}
					} else {
						if (o instanceof PackageFragment) {
							PackageFragment fragment = (PackageFragment) o;
							try {
								list.addAll(Arrays.asList(fragment
										.getCompilationUnits()));
							} catch (JavaModelException e) {
								e.printStackTrace();
							}

						}
					}
				}
			}
		}
	}
}
